﻿using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;
using Yoozoo.Gameplay.Liberty.AI;
using Yoozoo.Gameplay.Liberty.PlayerController;

namespace Yoozoo.Gameplay.Liberty.World
{
    public class PlayerWorldState : MonoBehaviour
    {
        [Range(0.01f,5f)]
        public float detectTime = 1f;
        private float _curDetectTime = 0f;

        [Range(0.5f,5f)]
        public float detectRadius = 2f;

        [Range(0.5f,5f)]
        public float playerObstacleDis = 1.5f;
        [Range(0.01f,2f)]
        public float crossObstacleDis = 0.85f;
        [Range(1,180)]
        public float playerObstacleAngle = 45f;
        
        [Range(0.01f,10f)]
        public float bargeTime = 3f;
        private float _curBargeTime = 0f;
        public bool isBarging = false;
        
        [Range(0,1)]
        public float bargeInputValue = 0.2f;
        [Range(0,5)]
        public float bargeVelocityMag = 1f;
        
        [Range(0,3)]
        public float bargeStayTime = 0.5f;
        public float _curBargeStayTime = 0f;
        
        private void Awake()
        {
            PlayerBargeComponent.onCollisionEnter += OnPlayerBargeEnter;
            //PlayerBargeComponent.onCollisionStay += OnPlayerBargeStay;
        }

        private void OnPlayerBargeEnter(Collision collision)
        {
            OnPlayerBarge(collision.collider);
        }

        // private void OnPlayerBargeStay(Collision collision)
        // {
        //     if (_curBargeStayTime > bargeStayTime)
        //     {
        //         OnPlayerBarge(collision.collider);
        //         _curBargeStayTime = 0;
        //     }
        // }

        private bool OnPlayerBarge(Collider collider)
        {
            LibertyAIUtils.PlayerController.viewAvatar.TriggerCollisionEnter(collider);


            var e = LibertyAIUtils.PlayerController.playerEntity.AIEntity;
            
            // 战斗状态下不允许推人
            if ((e.data.battleState!=BattleState.None && e.data.aimingState!=AimingState.None) || e.data.npcStatus != NpcStatus.None)
            {
                return false;
            }
            
            if (isBarging)
            {
                return false;
            } 
            
            var npcBirthManager = LibertyAIUtils.AIManager.NpcBirthManager;

            Rigidbody rig = LibertyAIUtils.PlayerController.rigidBody;
            PlayerInput playerInput = LibertyAIUtils.PlayerController.inputController.playInput;

            if ((Mathf.Abs(playerInput.HorRealValue) > bargeInputValue || Mathf.Abs(playerInput.VerRealValue) > bargeInputValue) 
                || (LibertyAIUtils.PlayerController.ControlMode == ControlMode.AutoNav || LibertyAIUtils.PlayerController.ControlMode == ControlMode.Hanging))
            {
                //if (rig.velocity.magnitude > bargeVelocityMag)
                {
                    if (npcBirthManager.col2AIEntityMap.TryGetValue(collider, out AIEntity aiEntity))
                    {
                        if (aiEntity.data.uniqueId != LibertyAIUtils.PLAYER_AI_ID)
                        {
                            // 是否可被推开
                            if (!aiEntity.data.canBeBarge)
                            {
                                return false;
                            }
                            
                            // 战斗状态不触发
                            if ((aiEntity.data.npcStatus & NpcStatus.Battle) > 0)
                            {
                                return false;
                            }

                            if ((aiEntity.data.npcStatus & NpcStatus.InCar) > 0 ||
                                (aiEntity.data.npcStatus & NpcStatus.ExpelCar) > 0)
                            {
                                return false;
                            }
                            
                            Vector3 v1 = aiEntity.data.position -
                                         LibertyAIUtils.PlayerController.playerModel.position;
                            v1.Normalize();
                            if (Vector3.Angle(v1, LibertyAIUtils.PlayerController.playerModel.forward) < 90) // 在玩家后方不触发撞击
                            {
                                if ((aiEntity.data.npcStatus & NpcStatus.PlayerBarge) <= 0)
                                {
                                    isBarging = true;
                                    aiEntity.data.npcStatus = NpcStatus.PlayerBarge;
                                    
                                    // 应用主角推人动作 
                                    Animator animator = LibertyAIUtils.PlayerController.viewAvatar.animator;
                                    Vector3 v2 = Vector3.Cross(LibertyAIUtils.PlayerController.playerModel.forward, v1);
                                    if (v2.y > 0)
                                    {
                                        // 右边
                                        animator.ResetTrigger("push_right");
                                        animator.SetTrigger("push_right");
                                    }
                                    else
                                    {
                                        animator.ResetTrigger("push_left");
                                        animator.SetTrigger("push_left");
                                    }
                                    aiEntity.viewer.animationAgent.SetSupportLookAtPlayer(true);
                                    return true;
                                }
                            }
                            
                        }
                    }
                }
            }

            return false;
        }

        private void FixedUpdate()
        {
            _curBargeStayTime += Time.fixedDeltaTime;
            if (_curBargeStayTime > bargeStayTime)
            {
                if (LibertyAIUtils.AIManager)
                {
                    foreach (var aiEntity in LibertyAIUtils.AIManager.NpcBirthManager.AIEntities)
                    {
                        var npc = aiEntity.Value;
                        if (LibertyAIUtils.PlayerController)
                        {
                            if (npc && npc.data.uniqueId != LibertyAIUtils.PLAYER_AI_ID)
                            {
                                if (npc.data.distanceToPlayer <= LibertyAIUtils.PlayerController.playerCollider.radius + npc.characterController.radius + 0.1f)
                                {
                                    OnPlayerBarge(npc.characterController);
                                    _curBargeStayTime = 0;
                                    break;
                                }
                            }
                        }
                    }
                }
                

            }
            
            if (isBarging)
            {
                _curBargeTime += Time.fixedDeltaTime;
                if (_curBargeTime > bargeTime)
                {
                    isBarging = false;
                    _curBargeTime = 0;
                }
            }
            
            _curDetectTime += Time.fixedDeltaTime;
            if (_curDetectTime > detectTime)
            {
                DetectNpc();
                _curDetectTime = 0f;
            }
            
        }
        

        private void DetectNpc()
        {
            if (!LibertyAIUtils.PlayerController)
            {
                return;
            }
            var player = LibertyAIUtils.PlayerController.playerModel;

            var npcMap= LibertyAIUtils.AIManager.NpcBirthManager.AIEntities;
            if (npcMap!=null)
            {
                foreach (var n in npcMap)
                {
                    if (n.Value.data.uniqueId == LibertyAIUtils.PLAYER_AI_ID)
                    {
                        continue;
                    }

                    if (!IsAvoidNpc(n.Value.data))
                    {
                        continue;
                    }

                    AIData aiData = n.Value.data;
                    var desPoint = LibertyAIUtils.TrafficManager.PathManager.GetPathPoint(aiData.pathId, aiData.pathPointIndex);
                    
                    if (desPoint == null) {
                        //Debug.LogError($"找不到路径点 npcId:{aiData.uniqueId} pathId:{aiData.pathId},pointIndex:{aiData.pathPointIndex}");
                        continue;
                    }
                    
                    float d = aiData.distanceToPlayer;
                    if (d <= detectRadius)
                    {
                        if ((aiData.npcStatus & NpcStatus.PlayerControl) == 0)
                        {
                            aiData.npcStatus = NpcStatus.PlayerControl;

                            float angle = Vector3.Angle(aiData.directionToPlayer, (desPoint.position - aiData.position));
                            if (angle < 90)
                            {
                                if (d < playerObstacleDis && angle < playerObstacleAngle)
                                {
                                    Vector3 c = aiData.directionToPlayer;
                                    Vector3 r = Vector3.Cross(aiData.forward, Vector3.up);

                                    float p = Mathf.Abs(Vector3.Dot(c, r));
                                    if (p < crossObstacleDis)
                                    {
                                        aiData.npcStatus |= NpcStatus.PlayerObstacle;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            
        }

        private bool IsAvoidNpc(AIData data)
        {
            if ((data.npcStatus & NpcStatus.PathControl) > 0)
            {
                return true;
            }
            
            if ((data.npcStatus & NpcStatus.PlayerControl) > 0)
            {
                return true;
            }
            return false;
        }
        
    }
}